﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using WindowsHookSample;
using System.Threading;
using Newtonsoft.Json.Linq;
using System.IO;

namespace TinyLayoutTool
{
    public partial class MainForm : Form
    {
        // 布局扩展常量
        private const uint WS_EX_LAYERED = 0x80000;
        // 穿透常量
        private const int WS_EX_TRANSPARENT = 0x20;
        // 扩展样式
        private const int GWL_EXSTYLE = (-20);
        // 原有串口扩展
        private uint intExTemp;
        // 原有窗口样式
        private uint oldGWLEx;

        // 正在设计布局
        private bool isEditing = false;
        // 分割树根节点
        private SpliterNode rootSpliter = null;
        // 当前的坐标位置
        private Point curPoint = new Point();
        // 最初的鼠标样式
        private Cursor oldCursor = null;
        // 当前高亮的分割器
        private SpliterNode curHighlightSpliter = null;

        private Rectangle curHighlightRect = new Rectangle();
        // 当前选中的分割器
        private SpliterNode curSpliter = null;
        // 鼠标是否按下判断
        private bool isMouseDown = false;

        private Screen otherScreen = null;

        // 其他屏幕列表
        private List<MainForm> otherScreenForm = new List<MainForm>();
        // 父窗口类
        public MainForm parent = null;

        private IntPtr targetHwnd = IntPtr.Zero;

        private Point oldPos = new Point();

        /// <summary>
        /// 在窗口结构中为指定的窗口设置信息
        /// </summary>
        /// <param name="hwnd">欲为其取得信息的窗口的句柄</param>
        /// <param name="nIndex">欲取回的信息</param>
        /// <param name="dwNewLong">由nIndex指定的窗口信息的新值</param>
        /// <returns></returns>
        [DllImport("user32", EntryPoint = "SetWindowLong")]
        private static extern uint SetWindowLong(IntPtr hwnd, int nIndex, uint dwNewLong);

        /// <summary>
        /// 从指定窗口的结构中取得信息
        /// </summary>
        /// <param name="hwnd">欲为其获取信息的窗口的句柄</param>
        /// <param name="nIndex">欲取回的信息</param>
        /// <returns></returns>
        [DllImport("user32", EntryPoint = "GetWindowLong")]
        private static extern uint GetWindowLong(IntPtr hwnd, int nIndex);
        
        /// <summary>
        /// 获取当前活动窗口
        /// </summary>
        /// <returns></returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags);

        [DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)]
        public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);

        [DllImport("user32.dll", EntryPoint = "WindowFromPoint")]//指定坐标处窗体句柄
        public static extern IntPtr WindowFromPoint(
            int xPoint,
            int yPoint
        );

        public struct RECT
        {
            public int Left; //最左坐标
            public int Top; //最上坐标
            public int Right; //最右坐标
            public int Bottom; //最下坐标
        }

        public MainForm()
        {
            InitForm(null);
        }

        public MainForm(Screen showScreen)
        {
            InitForm(showScreen);
        }

        private void InitForm(Screen otherScreen)
        {
            this.otherScreen = otherScreen;
            InitializeComponent();

            MouseHook.GlobalMouseDown += new EventHandler<MouseHook.MouseEventArgs>(MouseHook_GlobalMouseDown);
            MouseHook.GlobalMouseUp += new EventHandler<MouseHook.MouseEventArgs>(MouseHook_GlobalMouseUp);
            MouseHook.GlobalMouseMove += new EventHandler<MouseHook.MouseEventArgs>(MouseHook_GlobalMouseMove);

            if(otherScreen != null)
            {
                notifyIcon1.Visible = false;
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            // 窗体不出现在Windows任务栏中
            this.ShowInTaskbar = false;
            // 使鼠标穿透
            CanPenetrate();
            // 使窗体始终在其它窗体之上
            this.TopMost = true;
            // 记录鼠标样式
            oldCursor = this.Cursor;

            // 设置屏幕位置
            Screen tmpScreen = null;
            if (otherScreen == null)
            {
                tmpScreen = Screen.PrimaryScreen;

                // 显示其他窗口
                if (otherScreenForm.Count == 0)
                {
                    Screen[] screens = Screen.AllScreens;
                    foreach (Screen screen in screens)
                    {
                        if (tmpScreen == screen)
                        {
                            continue;
                        }
                        MainForm other = new MainForm(screen);
                        other.parent = this;
                        otherScreenForm.Add(other);
                        other.Show();
                    }
                }
            }
            else
            {
                tmpScreen = otherScreen;
            }
            Rectangle rect = tmpScreen.WorkingArea;
            this.Left = rect.Left;
            this.Top = rect.Top;
            this.Width = rect.Width;
            this.Height = rect.Height;


            ChangeEdit(true);
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // 处理其他屏幕
            foreach (MainForm form in otherScreenForm)
            {
                form.Close();
            }

            //关闭当前对象(即窗体) 
            this.Close();
            //通过Application类的静态方法Exit()退出应用程序 
            Application.Exit();
        }

        private void loadLayoutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.TopMost = false;
            openFileDialog1.FileName = "";
            openFileDialog1.Filter = "*.layout|*.layout";

            DialogResult result = openFileDialog1.ShowDialog();
            if(result == DialogResult.OK)
            {
                string layoutFile = openFileDialog1.FileName;
                string text = File.ReadAllText(layoutFile);
                if(text.Length != 0)
                {
                    JObject jObj = JObject.Parse(text);
                    FromJObject(jObj);
                }
            }
            this.TopMost = true;
        }

        private void saveLayoutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.TopMost = false;
            saveFileDialog1.FileName = "布局1.layout";
            saveFileDialog1.Filter = "*.layout|*.layout";

            DialogResult result = saveFileDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                string layoutFile = saveFileDialog1.FileName;
                string text = "";
                JObject jObj = ToJObject();
                text = jObj.ToString();
                File.WriteAllText(layoutFile, text);
            }
            this.TopMost = true;
        }

        private void editLayoutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeEdit(!isEditing);
        }

        private void showLayoutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeShow(!this.Visible);
        }

        private void insertHSpliterToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // 查找当前的split范围，以及父窗口split
            SpliterNode parent = FindInsertSplitNode(curPoint.X, curPoint.Y, rootSpliter);
            // 根据当前位置添加新的split
            InsertSpliter(parent, curPoint.Y, SpliterType.Horizontal);
            this.Invalidate();
        }

        private void insertVSpliterToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // 查找当前的split范围，以及父窗口split
            SpliterNode parent = FindInsertSplitNode(curPoint.X, curPoint.Y, rootSpliter);
            // 根据当前位置添加新的split
            InsertSpliter(parent, curPoint.X, SpliterType.Vertical);
            this.Invalidate();
        }

        private void deleteSpliterToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (curSpliter != null)
            {
                if (curSpliter.parentNode != null)
                {
                    if (curSpliter.parentNode.leftNode == curSpliter)
                    {
                        curSpliter.parentNode.leftNode = null;
                    }
                    else if (curSpliter.parentNode.rightNode == curSpliter)
                    {
                        curSpliter.parentNode.rightNode = null;
                    }
                }
                else
                {
                    rootSpliter = null;
                }
                this.Invalidate();
            }
        }
        
        private void finishEditToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeEdit(false);
            if(parent != null)
            {
                parent.ChangeEdit(false);
            }
        }


        private void applyLayoutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ApplyLayout();
        }

        private void layout22ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreateDefaultLayout(2, 2);
        }

        private void layout333ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreateDefaultLayout(3, 3);
        }

        private void layout21ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreateDefaultLayout(2, 1);
        }

        private void layout31ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreateDefaultLayout(3, 1);
        }

        private void layout12ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreateDefaultLayout(1, 2);
        }

        private void layout13ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreateDefaultLayout(1, 3);
        }

        private void MainForm_Paint(object sender, PaintEventArgs e)
        {
            DrawSpliter(e.Graphics, rootSpliter, 9);
            DrawHighlightSpliter(e.Graphics);
            if (isEditing)
            {
                DrawTitle("点击右键添加布局分割", e.Graphics);
            }
            else
            {
                DrawTitle("拖拽窗口进行布局绑定，完成后请隐藏布局", e.Graphics);
            }
        }

        private void MainForm_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isMouseDown = true;
            }
        }

        private void MainForm_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (curSpliter != null)
                {
                    contextMenuStripEdit.Show(this, e.Location);
                }
                else
                {
                    curPoint.X = e.X;
                    curPoint.Y = e.Y;
                    contextMenuStripInsert.Show(this, e.Location);
                }
            }
            isMouseDown = false;
        }

        private void MainForm_MouseMove(object sender, MouseEventArgs e)
        {
            if(isEditing)
            {
                if (isMouseDown)
                {
                    // 移动分割
                    if (curSpliter != null)
                    {
                        if (curSpliter.type == SpliterType.Horizontal)
                        {
                            curSpliter.UpdatePos(e.Y);
                            RefreshSpliterRect(curSpliter);
                        }
                        else if (curSpliter.type == SpliterType.Vertical)
                        {
                            curSpliter.UpdatePos(e.X);
                            RefreshSpliterRect(curSpliter);
                        }
                        this.Invalidate();
                    }
                }
                else
                {
                    // 查找鼠标悬停分割
                    SpliterNode findSpliter = FindMouseHoverSpliter(e.X, e.Y, rootSpliter);
                    if (findSpliter != null)
                    {
                        if (findSpliter.type == SpliterType.Horizontal)
                        {
                            this.Cursor = Cursors.HSplit;
                        }
                        else if (findSpliter.type == SpliterType.Vertical)
                        {
                            this.Cursor = Cursors.VSplit;
                        }
                        curSpliter = findSpliter;
                    }
                    else
                    {
                        curSpliter = null;
                        this.Cursor = oldCursor;
                    }
                }
            }
        }

        /// <summary>
        /// 切换编辑状态
        /// </summary>
        /// <param name="isEditing"></param>
        public void ChangeEdit(bool isEditing)
        {
            this.isEditing = isEditing;
            if(isEditing)
            {
                this.Opacity = 0.5;
                this.TransparencyKey = new Color();
                editLayoutToolStripMenuItem.Text = "完成布局设计";
                curHighlightSpliter = null;
                ChangeShow(true);
                MouseHook.Enabled = false;
                this.Invalidate();
                RestorePenetrate();
            }
            else
            {
                this.Opacity = 1;
                this.TransparencyKey = this.BackColor;
                editLayoutToolStripMenuItem.Text = "设计布局";

                MouseHook.Enabled = true;
                this.Invalidate();
                CanPenetrate();
            }

            // 处理其他屏幕
            foreach(MainForm form in otherScreenForm)
            {
                form.ChangeEdit(isEditing);
            }
        }

        /// <summary>
        /// 切换显示状态
        /// </summary>
        /// <param name="isVisible"></param>
        private void ChangeShow(bool isVisible)
        {
            this.Visible = isVisible;
            if(this.Visible)
            {
                showLayoutToolStripMenuItem.Text = "隐藏布局";
                if(!isEditing)
                {
                    MouseHook.Enabled = true;
                }
            }
            else
            {
                showLayoutToolStripMenuItem.Text = "显示布局";
                MouseHook.Enabled = false;
            }
            // 处理其他屏幕
            foreach (MainForm form in otherScreenForm)
            {
                form.ChangeShow(isVisible);
            }
        }

        /// <summary>
        /// 使窗口有鼠标穿透功能
        /// </summary>
        private void CanPenetrate()
        {
            //this.Focus();
            intExTemp = GetWindowLong(this.Handle, GWL_EXSTYLE);
            oldGWLEx = SetWindowLong(this.Handle, GWL_EXSTYLE, WS_EX_TRANSPARENT | WS_EX_LAYERED);
        }

        /// <summary>
        /// 恢复窗口鼠标穿透
        /// </summary>
        private void RestorePenetrate()
        {
            SetWindowLong(this.Handle, GWL_EXSTYLE, oldGWLEx);
        }

        /// <summary>
        /// 递归刷新整个分割树结构
        /// </summary>
        /// <param name="node"></param>
        private void RefreshSpliterRect(SpliterNode node)
        {
            if (node != null)
            {
                node.RefreshSubRect();
                if (node.leftNode != null)
                {
                    node.leftNode.RefreshRect(node.leftRect);
                    RefreshSpliterRect(node.leftNode);
                }
                if (node.rightNode != null)
                {
                    node.rightNode.RefreshRect(node.rightRect);
                    RefreshSpliterRect(node.rightNode);
                }
            }
        }

        /// <summary>
        /// 查找鼠标悬停的分割
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="node"></param>
        /// <returns></returns>
        private SpliterNode FindMouseHoverSpliter(int x, int y, SpliterNode node)
        {
            if (node != null)
            {
                if (node.IsMouseHover(x, y))
                {
                    return node;
                }
                else
                {
                    SpliterNode findNode = FindMouseHoverSpliter(x, y, node.leftNode);
                    if (findNode != null)
                    {
                        return findNode;
                    }
                    findNode = FindMouseHoverSpliter(x, y, node.rightNode);
                    if (findNode != null)
                    {
                        return findNode;
                    }
                    return null;
                }
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 查找插入分割的上层节点
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="node"></param>
        /// <returns></returns>
        private SpliterNode FindInsertSplitNode(int x, int y, SpliterNode node)
        {
            if (node != null && node.rect.Contains(x, y))
            {
                if (node.leftRect.Contains(x, y))
                {
                    if (node.leftNode == null)
                    {
                        return node;
                    }
                    else
                    {
                        return FindInsertSplitNode(x, y, node.leftNode);
                    }
                }
                else if (node.rightRect.Contains(x, y))
                {
                    if (node.rightNode == null)
                    {
                        return node;
                    }
                    else
                    {
                        return FindInsertSplitNode(x, y, node.rightNode);
                    }
                }
                else
                {
                    return node;
                }
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// 插入分割到当前位置
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="pos"></param>
        /// <param name="type"></param>
        private void InsertSpliter(SpliterNode parent, int pos, SpliterType type)
        {
            if (parent == null)
            {
                rootSpliter = new SpliterNode(this.ClientRectangle, pos, type);
            }
            else
            {
                if (parent.leftRect.Contains(curPoint.X, curPoint.Y))
                {
                    parent.leftNode = new SpliterNode(parent.leftRect, pos, type);
                    parent.leftNode.parentNode = parent;
                }
                else if (parent.rightRect.Contains(curPoint.X, curPoint.Y))
                {
                    parent.rightNode = new SpliterNode(parent.rightRect, pos, type);
                    parent.rightNode.parentNode = parent;
                }
            }
        }

        /// <summary>
        /// 绘制分割器树
        /// </summary>
        /// <param name="g"></param>
        /// <param name="node"></param>
        /// <param name="level"></param>
        private void DrawSpliter(Graphics g, SpliterNode node, int level)
        {
            if (node != null)
            {
                if (level < 0)
                {
                    level = 0;
                }

                Pen linePen = new Pen(Color.DarkBlue);
                linePen.Width = 3;
                SolidBrush fillBrush = new SolidBrush(Color.DarkGray);

                if (node.leftNode == null)
                {
                    Rectangle r = node.leftRect;
                    //g.FillRectangle(fillBrush, r.X + 1, r.Y + 1, r.Width - 1, r.Height - 1);
                    DrawSizeString(g, r);
                }
                if (node.rightNode == null)
                {
                    Rectangle r = node.rightRect;
                    //g.FillRectangle(fillBrush, r.X + 1, r.Y + 1, r.Width - 1, r.Height - 1);
                    DrawSizeString(g, r);
                }
                if (node.type == SpliterType.Horizontal)
                {
                    g.DrawLine(linePen, node.rect.Left, node.pos, node.rect.Right, node.pos);
                }
                else if (node.type == SpliterType.Vertical)
                {
                    g.DrawLine(linePen, node.pos, node.rect.Top, node.pos, node.rect.Bottom);
                }

                linePen.Dispose();

                // 绘制子节点
                DrawSpliter(g, node.leftNode, level - 1);
                DrawSpliter(g, node.rightNode, level - 1);
            }
        }

        /// <summary>
        /// 绘制高亮的分割器矩形框
        /// </summary>
        /// <param name="g"></param>
        private void DrawHighlightSpliter(Graphics g)
        {
            if (curHighlightSpliter != null)
            {
                Pen linePen = new Pen(Color.Red);
                linePen.Width = 6;
                Rectangle rect = new Rectangle();
                rect.X = curHighlightRect.X + 3;
                rect.Y = curHighlightRect.Y + 3;
                rect.Width = curHighlightRect.Width - 5;
                rect.Height = curHighlightRect.Height - 5;
                g.DrawRectangle(linePen, rect);

                linePen.Dispose();
            }
        }

        /// <summary>
        /// 绘制中心文本，添加边框
        /// </summary>
        /// <param name="g"></param>
        /// <param name="r"></param>
        private void DrawTitle(string title, Graphics g)
        {
            SolidBrush wordBrush = new SolidBrush(Color.Black);
            SolidBrush wordEdgeBrush = new SolidBrush(Color.White);
            Font wordFont = new Font("Times New Roman", 20);
            StringFormat stringFormat = new StringFormat();
            stringFormat.Alignment = StringAlignment.Center;
            stringFormat.LineAlignment = StringAlignment.Center;
            
            Rectangle r = new Rectangle(0, 0, this.Width, this.Height);
            int x = (r.Left + r.Right) / 2;
            int y = r.Top + 50;
            string text = title;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;

            for (int i = 1; i <= 1; ++i)
            {
                g.DrawString(text, wordFont, wordEdgeBrush, x + i, y, stringFormat);
                g.DrawString(text, wordFont, wordEdgeBrush, x - i, y, stringFormat);
                g.DrawString(text, wordFont, wordEdgeBrush, x, y + i, stringFormat);
                g.DrawString(text, wordFont, wordEdgeBrush, x, y - i, stringFormat);
                g.DrawString(text, wordFont, wordEdgeBrush, x + i, y + i, stringFormat);
                g.DrawString(text, wordFont, wordEdgeBrush, x - i, y - i, stringFormat);
                g.DrawString(text, wordFont, wordEdgeBrush, x - i, y + i, stringFormat);
                g.DrawString(text, wordFont, wordEdgeBrush, x + i, y - i, stringFormat);
            }

            g.DrawString(text, wordFont, wordBrush, x, y, stringFormat);

            wordBrush.Dispose();
            wordEdgeBrush.Dispose();
            wordFont.Dispose();
            stringFormat.Dispose();
        }

        /// <summary>
        /// 绘制中心文本，添加边框
        /// </summary>
        /// <param name="g"></param>
        /// <param name="r"></param>
        private void DrawSizeString(Graphics g, Rectangle r)
        {
            SolidBrush wordBrush = new SolidBrush(Color.White);
            SolidBrush wordEdgeBrush = new SolidBrush(Color.Black);
            Font wordFont = new Font("Times New Roman", 14);
            StringFormat stringFormat = new StringFormat();
            stringFormat.Alignment = StringAlignment.Center;
            stringFormat.LineAlignment = StringAlignment.Center;

            string text = string.Format("{0}×{1}", r.Width, r.Height);
            int x = (r.Left + r.Right) / 2;
            int y = (r.Top + r.Bottom) / 2;

            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;

            for (int i = 1; i <= 1; ++i)
            {
                g.DrawString(text, wordFont, wordEdgeBrush, x + i, y, stringFormat);
                g.DrawString(text, wordFont, wordEdgeBrush, x - i, y, stringFormat);
                g.DrawString(text, wordFont, wordEdgeBrush, x, y + i, stringFormat);
                g.DrawString(text, wordFont, wordEdgeBrush, x, y - i, stringFormat);
                g.DrawString(text, wordFont, wordEdgeBrush, x + i, y + i, stringFormat);
                g.DrawString(text, wordFont, wordEdgeBrush, x - i, y - i, stringFormat);
                g.DrawString(text, wordFont, wordEdgeBrush, x - i, y + i, stringFormat);
                g.DrawString(text, wordFont, wordEdgeBrush, x + i, y - i, stringFormat);
            }

            g.DrawString(text, wordFont, wordBrush, x, y, stringFormat);

            wordBrush.Dispose();
            wordEdgeBrush.Dispose();
            wordFont.Dispose();
            stringFormat.Dispose();
        }

        /// <summary>
        /// 全局鼠标按下
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MouseHook_GlobalMouseDown(object sender, MouseHook.MouseEventArgs e)
        { 
            if(e.Button == Buttons.Left)
            {
                isMouseDown = true;           
            }
        }

        /// <summary>
        /// 全局鼠标抬起
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MouseHook_GlobalMouseUp(object sender, MouseHook.MouseEventArgs e)
        {
            isMouseDown = false;
            if(this.Visible && !isEditing)
            {
                // 获得焦点窗口
                if (targetHwnd != IntPtr.Zero && !IsSameFormHandle(targetHwnd))
                {
                    // 获得窗口大小
                    RECT rect = new RECT();
                    GetWindowRect(targetHwnd, ref rect);

                    // 当前鼠标位置
                    Point tmpP = new Point(e.X, e.Y);
                    Point p = this.PointToClient(tmpP);

                    if (curHighlightRect.Contains(p))
                    {
                        ApplyRect2Window(targetHwnd, curHighlightRect);
                    }

                    if(curHighlightSpliter != null)
                    {
                        if(curHighlightSpliter.leftRect.Contains(p))
                        {
                            ClearSameHwnd(targetHwnd, this);
                            // 清除本框架的其他句柄
                            ClearSameHwnd(targetHwnd, rootSpliter);
                            curHighlightSpliter.leftHwnd = targetHwnd;
                        }
                        else if (curHighlightSpliter.rightRect.Contains(p))
                        {
                            ClearSameHwnd(targetHwnd, this);
                            // 清除本框架的其他句柄
                            ClearSameHwnd(targetHwnd, rootSpliter);
                            curHighlightSpliter.rightHwnd = targetHwnd;
                        }
                    }
                }
                curHighlightSpliter = null;
                curHighlightRect = new Rectangle();
                targetHwnd = IntPtr.Zero;
                this.Invalidate();
            }
        }

        /// <summary>
        /// 全局鼠标移动事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MouseHook_GlobalMouseMove(object sender, MouseHook.MouseEventArgs e)
        {
            if (!isEditing && isMouseDown && this.Visible)
            {
                RECT rect = new RECT();
                if(targetHwnd == IntPtr.Zero)
                {
                    // 重新获得焦点窗口
                    IntPtr hwd = GetForegroundWindow();//WindowFromPoint(e.X, e.Y);
                    if (hwd != IntPtr.Zero && !IsSameFormHandle(hwd))
                    {
                        // 获得窗口大小
                        GetWindowRect(hwd, ref rect);
                        oldPos.X = rect.Left;
                        oldPos.Y = rect.Top;
                        targetHwnd = hwd;
                    }
                }

                // 获得焦点窗口
                if (targetHwnd == IntPtr.Zero || IsSameFormHandle(targetHwnd))
                {
                    return;
                }
                // 获得窗口大小
                GetWindowRect(targetHwnd, ref rect);
                // 判定是否移动了窗口
                if(oldPos.X != rect.Left || oldPos.Y != rect.Top)
                {
                    oldPos.X = rect.Left;
                    oldPos.Y = rect.Top;
                }
                else
                {
                    return;
                }

                // 当前鼠标位置
                Point tmpP = new Point(e.X, e.Y);
                Point p = this.PointToClient(tmpP);

                // 判定当前
                SpliterNode findSpliter = FindInsertSplitNode(p.X, p.Y, rootSpliter);

                if (findSpliter != null)
                {
                    Rectangle tmpRect = new Rectangle();
                    if (findSpliter.leftRect.Contains(p.X, p.Y))
                    {
                        tmpRect = findSpliter.leftRect;
                    }
                    else if (findSpliter.rightRect.Contains(p.X, p.Y))
                    {
                        tmpRect = findSpliter.rightRect;
                    }

                    if (!curHighlightRect.Equals(tmpRect))
                    {
                        curHighlightSpliter = findSpliter;
                        curHighlightRect = tmpRect;
                        this.Invalidate();
                    }
                }
                //labelPoint.Text = string.Format("（{0}，{1}）", x, y);
                //int hwnd = WindowFromPoint(x, y);//获取指定坐标处窗口的句柄
                //labelHandle.Text = hwnd.ToString();
            }
        }

        /// <summary>
        /// 开启线程应用大小和位置到窗口，防止因鼠标操作Move窗口造成的SetWindowPos失败
        /// </summary>
        /// <param name="hwd"></param>
        /// <param name="curRect"></param>
        private void ApplyRect2Window(IntPtr hwd, Rectangle curRect)
        {
            Point pp = this.PointToScreen(new Point(curRect.X, curRect.Y));
            WindowPos wPos = new WindowPos();
            wPos.hWnd = hwd;
            wPos.x = pp.X;
            wPos.y = pp.Y;
            wPos.width = curRect.Width;
            wPos.height = curRect.Height;
            Thread thread = new Thread(new ParameterizedThreadStart(SetWindowPositionThread));
            thread.Start(wPos);
        }

        /// <summary>
        /// 设置窗口位置线程方法
        /// </summary>
        /// <param name="obj"></param>
        private void SetWindowPositionThread(Object obj)
        {
            Thread.Sleep(100);
            WindowPos wPos = (WindowPos)obj;
            // 设置窗口位置和大小
            ShowWindow(wPos.hWnd, 1); 
            SetWindowPos(wPos.hWnd, -1, wPos.x, wPos.y, wPos.width, wPos.height, 4);
        }

        /// <summary>
        /// 应用布局
        /// </summary>
        public void ApplyLayout()
        {
            ApplyLayout(rootSpliter);

            // 处理其他屏幕
            foreach (MainForm form in otherScreenForm)
            {
                form.ApplyLayout();
            }
        }

        /// <summary>
        /// 递归应用布局到绑定窗口
        /// </summary>
        /// <param name="node"></param>
        private void ApplyLayout(SpliterNode node)
        {
            if(node != null)
            {
                if(node.leftNode == null)
                {
                    if(node.leftHwnd != IntPtr.Zero)
                    {
                        ApplyRect2Window(node.leftHwnd, node.leftRect);
                    }
                }
                else
                {
                    ApplyLayout(node.leftNode);
                }

                if (node.rightNode == null)
                {
                    if (node.rightHwnd != IntPtr.Zero)
                    {
                        ApplyRect2Window(node.rightHwnd, node.rightRect);
                    }
                }
                else
                {
                    ApplyLayout(node.rightNode);
                }
            }
        }

        /// <summary>
        /// 生成默认的布局，减少设计复杂度
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        private void CreateDefaultLayout(int x, int y)
        {
            // 先横再竖，先上后下，先左后右
            if(x == y)
            {
                // 插入乘法原则的矩阵 如2*2 3*3
                Rectangle rect = this.ClientRectangle;
                int xSpace = rect.Width / x;
                int ySpace = rect.Height / x;
                Rectangle tmpRectX = new Rectangle();
                Rectangle tmpRectY = new Rectangle();
                SpliterNode rootNode = null;
                SpliterNode lastNodeX = null;
                SpliterNode lastNodeY = null;
                // 插入x
                for (int i = 0; i < (x - 1); ++i)
                {
                    tmpRectX.X = rect.X;
                    tmpRectX.Y = rect.Y;
                    tmpRectX.Width = rect.Width;
                    tmpRectX.Height = rect.Height - i * ySpace;
                    SpliterNode tmpX = new SpliterNode(tmpRectX, ySpace * (i + 1), SpliterType.Horizontal);
                    
                    // 插入y
                    lastNodeY = null;
                    for (int j = 0; j < (y - 1); ++j)
                    {
                        Rectangle r = tmpX.leftRect;
                        tmpRectY.X = r.X;
                        tmpRectY.Y = r.Y;
                        tmpRectY.Width = r.Width - j * xSpace;
                        tmpRectY.Height = r.Height;
                        SpliterNode tmpY = new SpliterNode(tmpRectY, xSpace * (j + 1), SpliterType.Vertical);

                        if (lastNodeY == null)
                        {
                            tmpX.leftNode = tmpY;
                        }
                        else
                        {
                            lastNodeY.rightNode = tmpY;
                        }
                        lastNodeY = tmpY;
                    }

                    // 处理最后一个
                    if(i == (x - 2))
                    {
                        lastNodeY = null;
                        for (int j = 0; j < (y - 1); ++j)
                        {
                            Rectangle r = tmpX.leftRect;
                            tmpRectY.X = r.X;
                            tmpRectY.Y = r.Y;
                            tmpRectY.Width = r.Width - j * xSpace;
                            tmpRectY.Height = r.Height;
                            SpliterNode tmpY = new SpliterNode(tmpRectY, xSpace * (j + 1), SpliterType.Vertical);

                            if (lastNodeY == null)
                            {
                                tmpX.rightNode = tmpY;
                            }
                            else
                            {
                                lastNodeY.rightNode = tmpY;
                            }
                            lastNodeY = tmpY;
                        }
                    }

                    if (lastNodeX == null)
                    {
                        rootNode = tmpX;
                    }
                    else
                    {
                        lastNodeX.rightNode = tmpX;
                    }
                    lastNodeX = tmpX;
                }

                rootSpliter = rootNode;
                RefreshSpliterRect(rootSpliter);
            }
            else 
            {
                // 仅仅包含两列，数字大的占1/3，数字小的占2/3
                Rectangle rect = this.ClientRectangle;
                int xPos = 0;
                if(x < y)
                {
                    xPos = rect.Width * 2 / 3;
                }
                else
                {
                    xPos = rect.Width * 1 / 3;
                }
                SpliterNode rootNode = new SpliterNode(rect, xPos, SpliterType.Vertical);

                int lSpace = rect.Height / x;
                int rSpace = rect.Height / y;

                SpliterNode lastNode = null;
                Rectangle tmpRect = new Rectangle();
                // 插入左边
                for (int i = 0; i < (x - 1); ++i)
                {
                    Rectangle r = rootNode.leftRect;
                    tmpRect.X = r.X;
                    tmpRect.Y = r.Y;
                    tmpRect.Width = r.Width;
                    tmpRect.Height = r.Height - i * lSpace;
                    SpliterNode tmp = new SpliterNode(tmpRect, lSpace * (i + 1), SpliterType.Horizontal);
                    if (lastNode == null)
                    {
                        rootNode.leftNode = tmp;
                    }
                    else
                    {
                        lastNode.rightNode = tmp;
                    }
                    lastNode = tmp;
                }

                lastNode = null;
                // 插入右边
                for (int i = 0; i < (y - 1); ++i)
                {
                    Rectangle r = rootNode.rightRect;
                    tmpRect.X = r.X;
                    tmpRect.Y = r.Y;
                    tmpRect.Width = r.Width;
                    tmpRect.Height = r.Height - i * rSpace;
                    SpliterNode tmp = new SpliterNode(tmpRect, rSpace * (i + 1), SpliterType.Horizontal);
                    if (lastNode == null)
                    {
                        rootNode.rightNode = tmp;
                    }
                    else
                    {
                        lastNode.rightNode = tmp;
                    }
                    lastNode = tmp;
                }

                rootSpliter = rootNode;
                RefreshSpliterRect(rootSpliter);
            }

            this.Invalidate();
        }

        /// <summary>
        /// 从json对象中建立分割器
        /// </summary>
        /// <param name="jObj"></param>
        public void FromJObject(JObject jObj)
        {
            if(rootSpliter == null)
            {
                rootSpliter = new SpliterNode();
            }
            rootSpliter.FromJsonObject(jObj);
            RefreshSpliterRect(rootSpliter);
            this.Invalidate();

            // 处理其他屏幕
            if (jObj.Property("otherScreenForm") != null)
            {
                JArray jArray = (JArray)jObj.Property("otherScreenForm").Value;
                int index = 0;
                foreach(JObject tmpObj in jArray)
                {
                    if(index >= 0 && index < otherScreenForm.Count)
                    {
                        otherScreenForm[index].FromJObject(tmpObj);
                    }
                    index++;
                }
            }
        }

        /// <summary>
        /// 将分割器信息写入json对象
        /// </summary>
        /// <returns></returns>
        public JObject ToJObject()
        {
            JObject jObj = null;
            if (rootSpliter != null)
            {
                jObj = rootSpliter.ToJsonObject();
            }
            else
            {
                jObj = new JObject();
            }

            // 处理其他屏幕
            JArray jArray = new JArray();
            foreach (MainForm form in otherScreenForm)
            {
                JObject tmp = form.ToJObject();
                jArray.Add(tmp);
            }
            jObj["otherScreenForm"] = jArray;

            return jObj;
        }

        /// <summary>
        /// 清除除去来源之外的窗口句柄绑定
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="src"></param>
        public void ClearSameHwnd(IntPtr hwnd, MainForm src)
        {
            if (this != src)
            {
                // 清除本类的相同句柄
                ClearSameHwnd(hwnd, rootSpliter);
            }
            else
            {
                // 如果含有父窗口，则开始清除其他窗口
                if(parent != null)
                {
                    parent.ClearSameHwnd(hwnd, src);
                }
                // 否则清除其他屏幕窗口
                foreach (MainForm form in otherScreenForm)
                {
                    if(form != src)
                    {
                        form.ClearSameHwnd(hwnd, src);
                    }
                }
            }
        }
        /// <summary>
        /// 递归清除句柄
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="node"></param>
        private void ClearSameHwnd(IntPtr hwnd, SpliterNode node)
        {
            if(node != null)
            {
                if(node.leftNode == null)
                {
                    if (node.leftHwnd == hwnd)
                    {
                        node.leftHwnd = IntPtr.Zero;
                        Console.WriteLine("Clear Left");
                    }
                }
                else
                {
                    ClearSameHwnd(hwnd, node.leftNode);
                }

                if (node.rightNode == null)
                {
                    if (node.rightHwnd == hwnd)
                    {
                        node.rightHwnd = IntPtr.Zero;
                        Console.WriteLine("Clear Right");
                    }
                }
                else
                {
                    ClearSameHwnd(hwnd, node.rightNode);
                }
            }
        }

        public bool IsSameFormHandle(IntPtr hwnd)
        {
            if(this.Handle == hwnd)
            {
                return true;
            }

            foreach(MainForm other in otherScreenForm)
            {
                if(other.Handle == hwnd)
                {
                    return true;
                }
            }
            return false;
        }
    }
}
